<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Redis 消息订阅与发布</title>
    <link rel="stylesheet" type="text/css" th:href="@{/layui/css/layui.css}">
    <link rel="shortcut icon" th:href="@{/ico/favicon.ico}">
    <link  rel="stylesheet" type="text/css" th:href="@{/css/client.css}">
</head>
<body>
<div class="layui-container">
    <fieldset class="layui-elem-field layui-field-title" style="margin-top: 25px;">
        <legend style="margin-left: 40%;">基于Redis消息订阅与发布聊天界面</legend>
    </fieldset>
    <div class="layui-row layui-col-space5">
        <div class="layui-col-md4">
            <blockquote class="layui-elem-quote">用户信息</blockquote>
            <form class="layui-form">
                <div class="layui-form-item">
                    <div class="layui-inline">
                        <label class="layui-form-label">用户Id</label>
                        <div class="layui-input-inline">
                            <input id="userId" autocomplete="off" class="layui-input">
                        </div>
                    </div>
                    <div class="layui-inline">
                        <label class="layui-form-label">接收人Id</label>
                        <div class="layui-input-inline">
                            <input id="toUserId" autocomplete="off" class="layui-input">
                        </div>
                    </div>
                </div>
                <div class="layui-form-item">
                    <div class="layui-input-block">
                        <button class="layui-btn" onclick="start()" type="button">建立连接</button>
                    </div>
                </div>
            </form>
        </div>
        <div class="layui-col-md8">
            <blockquote class="layui-elem-quote">接收信息区</blockquote>
            <fieldset class="layui-elem-field layui-field-title">
                <legend>消息记录</legend>
            </fieldset>
            <div class="layui-tab layui-tab-card" style="height: 200px;overflow: auto">
                <div id="msgDiv">

                </div>
            </div>
        </div>
    </div>
    <div class="layui-row">
        <div class="layui-col-xs12">
            <div class="layui-form-item layui-form-text">
                <label class="layui-form-label">消息</label>
                <div class="layui-input-block">
                    <textarea placeholder="请输入内容" class="layui-textarea" id="msg"></textarea>
                </div>
            </div>
            <div class="layui-form-item">
                <div class="layui-input-block">
                    <button type="button" class="layui-btn layui-btn-normal" onclick="sendMsg()">发送消息
                    </button>
                </div>
            </div>
        </div>
    </div>

</div>
<script type="application/javascript" th:src="@{/jquery-2.1.4.js}"></script>
<!--layui-->
<script type="application/javascript" th:src="@{/layui/layui.js}"></script>
<script>
    var ws = null;
    var layer = null;

    layui.use(['layer'], function () {
        $(function () {
            layer = layui.layer;
        });
    });


    function start() {
        if (typeof (WebSocket) == "undefined") {
            layer.msg('您的浏览器不支持WebSocket', {icon: 5})
            return false;
        }

        var userId = $("#userId").val();
        if (userId == '' || userId == null) {
            layer.msg('请输入您的用户Id', {icon: 5})
            return false;
        }

        //实现化WebSocket对象，指定要连接的服务器地址与端口  建立连接
        var socketUrl = "" + window.location.protocol + "//" + window.location.host + "/chat/" + userId;
        socketUrl = socketUrl.replace("https", "ws").replace("http", "ws");
        if (ws != null) {
            ws.close();
            ws = null;
        }
        ws = new WebSocket(socketUrl);
        ws.binaryType = 'arraybuffer'
        //打开事件
        ws.onopen = function () {
            layer.msg('已建立WebSocket连接', {icon: 1})
        };
        //关闭事件
        ws.onclose = function () {
            layer.msg('websocket已关闭', {icon: 5})
        };
        //发生了错误事件
        ws.onerror = function () {
            layer.msg('websocket发生了错误', {icon: 5})
        };
        /**
         * 接收消息
         * @param msg
         */
        ws.onmessage = function (msg) {
            msg = JSON.parse(ArrayBufferUTF8ToStr(msg.data))
            $("#msgDiv").append('' +
                '<div class="other-msg-container">' +
                '   <img class="left-img" src="/images/left.png">' +
                '   <div class="other-msg msg-common">' +
                '       <p class="student">用户名：' + msg.sender + '</p><p class="chat">' + msg.msg + '</p>' +
                '   </div>' +
                '</div>');
            scroolBottom();
        };

    }

    function sendMsg() {
        if (!ws) {
            layer.msg('请先建立连接', {icon: 5});
            return false;
        }
        var msg = $("#msg").val();
        if (msg == '' || msg == null) {
            layer.msg('消息内容不能为空', {icon: 5});
            return;
        }
        var receiver = $("#toUserId").val();
        if (receiver == '' || receiver == null) {
            layer.msg('请输入接收人', {icon: 5});
            return;
        }
        var msgObj = {
            "receiver": receiver,
            "msg": msg
        };
        try {
            if (ws.readyState == 1) {
                ws.send(JSON.stringify(msgObj));
                $("#msgDiv").append('' +
                    '<div class="my-msg-container">' +
                    '   <img class="right-img" src="/images/right.png">' +
                    '   <div class="my-msg msg-common">' +
                    '       <p class="student">用户名：' + $("#userId").val() + '</p><p class="chat">' + msgObj.msg + '</p>' +
                    '   </div>' +
                    '</div>');
                scroolBottom()
                $("#msg").val('');
            } else {
                layer.msg('请检查连接是否正常？', {icon: 5});
            }
        } catch (e) {
            layer.msg('消息发送失败...', {icon: 5})
        }
    }

    /**
     * 滚动至底部
     */
    function scroolBottom(){
        var $div = document.getElementById("msgDiv");
        $div.scrollTop = $div.scrollHeight;
    }


    function ArrayBufferUTF8ToStr(array) {
        var out,i,len,c;
        var char2,char3;
        if (array instanceof ArrayBuffer) {
            array = new Uint8Array(array);
        }
        out = "";
        len = array.length;
        i = 0;
        while(i < len) {
            c = array[i++];
            switch(c >> 4) {
                case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
                    // 0xxxxxxx
                    out += String.fromCharCode(c);
                    break;
                case 12: case 13:
                    // 110x xxxx   10xx xxxx
                    char2 = array[i++];
                    out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
                    break;
                case 14:
                    // 1110 xxxx  10xx xxxx  10xx xxxx
                    char2 = array[i++];
                    char3 = array[i++];
                    out += String.fromCharCode(((c & 0x0F) << 12) |
                        ((char2 & 0x3F) << 6) |
                        ((char3 & 0x3F) << 0));
                    break;
            }
        }
        return out;
    }
</script>
</body>
</html>
